package org.tangerinejunction.imstats.sandbox;
import java.io.*;
import java.util.*;
import java.util.regex.*;
import org.tangerinejunction.imstats.data.*;
import org.tangerinejunction.imstats.util.*;
import org.tangerinejunction.imstats.logs.AdiumLogReader;
import org.tangerinejunction.imstats.logs.LogFile;

public class WordCounts {

  static final Comparator<Pair<String, Integer>> rankOrderDescending =
    new Comparator<Pair<String, Integer>>() {
      public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) {
        return (o2.second.compareTo(o1.second));
      }
  };
  
  /**
   * @param args
   */
  public static void main(String[] args) {
    IMDataset data = new IMDataset();
    long start = System.currentTimeMillis();
    File baseFolder = new File(System.getProperty("user.home") + "/Library/Application Support/Adium 2.0/Users/Default/Logs");
    File objectFolder = new File(System.getProperty("user.home") +"/Library/Application Support/Adium 2.0/Users/Default/ByObject");
    AdiumLogReader.readLogs(baseFolder, objectFolder, data);
    System.out.println("scan took " + (System.currentTimeMillis() - start)/ 1000 + " seconds");
    System.out.println("saw "+ data.getLogFiles().size() + " files");
    System.out.println("total of " + data.getAccountTable().getRowCount() + " accounts");
    System.out.println("total of " + data.getEntityTable().getRowCount() + " entities");
    System.out.println("about to start crunching...");
    WordFreqTable globalFrequencies  = new WordFreqTable();
    try {
      for(LogFile lf: data.getLogFiles()) {
        Conversation c = slurpFile(lf);
        
        for(String msg: c.lines) {
          String[] wordInMsg = msg.split(" ");
          for(String s: wordInMsg) {
        	  if (s.length() > 0)
        		  globalFrequencies.add(clean(s));
          }
        }
      }
    } catch(IOException e) {
      e.printStackTrace();
    }
    
    System.out.println(globalFrequencies.distinct() + " distinct words, " + globalFrequencies.total() + " total");
    
    ArrayList<Pair<String,Integer>> wordsByFreq = globalFrequencies.get();
    Collections.sort(wordsByFreq, rankOrderDescending);
    int i = 0;
    int index = 0;
    while (i < 50 && i < wordsByFreq.size()) {
      Pair<String,Integer> p = wordsByFreq.get(index);
      index++;
      if (Arrays.binarySearch(Constants.stopWords, p.first) < 0) {
    	  System.out.println(p.second + " " + p.first);
    	  i++;
      }
    }
    dumpWordFreqs(wordsByFreq);
  }
  
  private static void dumpWordFreqs(ArrayList<Pair<String, Integer>> wordsByFreq)  {
    try {
      PrintWriter pw = new PrintWriter(new FileWriter("wordFreqs.out"));
      int i =0;
      for(Pair<String, Integer> p : wordsByFreq)
        pw.println( (++i) + " " + p.second + " " + p.first);
      pw.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  // TODO: This function needs to be way more complicated.
  static String clean(String s) {
    String r;
    if(s.length() > 1 && (s.endsWith(".") || s.endsWith(",") || s.endsWith("?") || s.endsWith(";") || s.endsWith("!")))
      r= s.substring(0, s.length()-1);
    else
      r = s;
    r = r.replaceAll("&apos;", "'");
    return r.toLowerCase();  
  }
  
  static Pattern NoMatch = Pattern.compile("XXXNoMatch");

  static Pattern AHLogPat = Pattern.compile(
      ".+<span class=\"sender\">([^:]+): </span><pre class=\"message\">(.+)</pre></div>", Pattern.DOTALL );
  static Pattern ChatLogPat = Pattern.compile(
      "<message sender=\"([^\"]+)\".+<span [^>]+>(.+)</span></div></message>", Pattern.DOTALL );
  static Pattern XmlLogPat = Pattern.compile( 
      "<message sender=\"([^\"]+)\".+<span [^>]+>(.+)</span></div></message>", Pattern.DOTALL);

  static Conversation slurpFile(LogFile lf) throws IOException {
      Reader in = new InputStreamReader(new BufferedInputStream(new FileInputStream(lf)));

      Pattern pat;
      if(lf.getName().endsWith("AdiumHTMLLog")) {
        pat = AHLogPat;
      } else if(lf.getName().endsWith("chatlog"))
        pat = ChatLogPat;
      else 
        if(lf.getName().endsWith("xml")){
        pat = XmlLogPat;
      } else {
        System.err.println("flummoxed by file " + lf);
        pat = NoMatch;
      } 
      
      //read the whole file into a buffer
      int len = (int) lf.length();
      char[] content = new char[len];
      int t = 0;
      int count = 0;
      while( (count=in.read( content, t, len-t)) >0 )
        t+=count;

      in.close();
      Conversation c = new Conversation();
      String ln;

      int sta =0, end =0;
      while(sta < content.length) {
        do 
          end++;
        while(end < content.length && content[end] != '\n');
        ln = new String(content, sta, end-sta);
        sta = end+1;
        
        Matcher m = pat.matcher(ln);
        if(m.matches()) {
          c.add(m.group(1), m.group(2));
        }
      }
      return c;
    }
  

}
